import java.util.ArrayList;

/*
* Класс, собирающий статистику по месяцу
*/
public class MonthlyRecords {
    private final ArrayList<AccountingRecord> records
            = new ArrayList<>(); //Общие записи за месяц

    //Статистика, чтобы не обращаться каждый раз к записям.
    private int debitSum;//Доходы
    private int creditSum;//Расходы
    private int debitRecordsNum;
    private int creditRecordsNum;
    private AccountingRecord maxDebit;
    private AccountingRecord maxCredit;

    MonthlyRecords() {

    }
    MonthlyRecords(Tuple tuple) {
        addRecord(tuple);
    }
    MonthlyRecords(final ArrayList<Tuple> list) {
        addList(list);
    }

    private void increaseNum(final boolean isCredit) {
        if (isCredit) {
            ++creditRecordsNum;
            return;
        }
        ++debitRecordsNum;
    }
    private void increaseSum(final boolean isCredit, final int addSum) {
        if (isCredit) {
            creditSum += addSum;
            return;
        }
        debitSum += addSum;
    }
    private void updateMaxCredit(final AccountingRecord checkingRecord) {
        if (maxCredit == null) maxCredit = checkingRecord;
        if (maxCredit.isLessThan(checkingRecord)) {
            maxCredit = checkingRecord;
        }
    }
    private void updateMaxDebit(final AccountingRecord checkingRecord) {
        if (maxDebit == null) maxDebit = checkingRecord;
        if (maxDebit.isLessThan(checkingRecord)) {
            maxDebit = checkingRecord;
        }
    }
    private void checkMax(final AccountingRecord checkingRecord) {
        if (checkingRecord.isExpense) {
            updateMaxCredit(checkingRecord);
            return;
        }
        updateMaxDebit(checkingRecord);
    }

    public int getSum(boolean isExpense) {
        return isExpense? creditSum : debitSum;
    }
    public int getNum(boolean isCredit) {
        return isCredit? creditRecordsNum : debitRecordsNum;
    }
    public int getIncome() {
        return debitSum - creditSum;
    }
    public AccountingRecord getMax(boolean isCredit) {
        return isCredit? maxCredit : maxDebit;
    }

    public void addList(final ArrayList<Tuple> list) {
        for (Tuple tuple : list) {
            this.addRecord(tuple);
        }
    }
    public void addRecord(final Tuple tuple) {
        AccountingRecord record = new AccountingRecord(tuple);
        records.add(record);
        increaseNum(record.isExpense);
        increaseSum(record.isExpense, record.countSum());
        checkMax(record);
    }

    public String getStatistics() {
        return
                String.format("    Самый прибыльный товар:%n        %s%n", maxDebit.toString()) +
                String.format("    Самая крупная трата:%n        %s%n", maxCredit.toString());
    }
    public String compare(final ArrayList<Tuple> tuples) {
        String ret = "Совпадает";
        for (Tuple tuple : tuples) {
            Object[] record;
            try {
                record = tuple.unpack(new String[]{"Integer", "Boolean"});
            } catch (Exception exception) {
                System.err.println(exception.getMessage());
                return "Ошибка";
            }
            if (!(Boolean) record[1]) {
                if (debitSum != ((Integer) record[0]).intValue()) {
                    return String.format("Противоречит: ожидался доход " +
                            "%9d у.е.; получено %9d у.е.", debitSum, (Integer) record[0]);
                }
                continue;
            }
            if (creditSum != ((Integer) record[0]).intValue()) {
                return String.format("Противоречит: ожидалась трата %9d у.е.;" +
                        " получено %9d у.е.", creditSum, (Integer) record[0]);
            }
        }
        return "Совпадает";
    }
}
